package simpledb.storage;

import simpledb.common.Type;
import simpledb.execution.Predicate;

import java.io.DataOutputStream;
import java.io.IOException;

/**
 * 表示一个存储单个整数的字段（Field）。
 * IntField 是 Field 接口的一个实现，用于处理 INT_TYPE 类型的字段值。
 * 这个类的主要功能包括：
 * 1、存储一个整数值；
 * 2、提供字符串表示、哈希值计算、相等性比较等功能；
 * 3、支持与其他字段进行比较操作（如等于、大于、小于等）；
 * 4、实现字段的序列化（用于写入磁盘或网络传输）；
 * 5、返回字段的数据类型（Type.INT_TYPE）。
 */
public class IntField implements Field {

    // 序列化版本号 Field 继承了 Serializable
    private static final long serialVersionUID = 1L;

    // 字段的实际整数值
    private final int         value;

    /**
     * 构造函数：创建一个包含指定整数值的 IntField 对象
     *
     * @param value 要存储的整数值
     */
    public IntField(int value) {
        this.value = value;
    }

    /**
     * 获取该字段的整数值
     *
     * @return 字段值
     */
    public int getValue() {
        return value;
    }

    /**
     * 返回该字段的字符串表示形式（即整数的字符串）
     *
     * @return 字符串表示的整数值
     */
    public String toString() {
        return Integer.toString(value);
    }

    /**
     * 返回该字段的哈希码（基于整数值）
     *
     * @return 哈希码
     */
    public int hashCode() {
        return value;
    }

    /**
     * 判断两个 IntField 是否相等（基于它们的整数值）
     *
     * @param field 要比较的对象
     * @return 如果是 IntField 且值相同则返回 true，否则 false
     */
    public boolean equals(Object field) {
        if (!(field instanceof IntField))
            return false;
        return ((IntField) field).value == value;
    }

    /**
     * 返回该字段的数据类型
     *
     * @return Type.INT_TYPE 表示这是一个整数类型字段
     */
    @Override
    public Type getType() {
        return Type.INT_TYPE;
    }

    /**
     * 比较当前字段与给定字段的值，根据指定的操作符 op 进行判断。
     *
     * @param op 比较操作符（如 EQUALS, GREATER_THAN 等）
     * @param val 要比较的字段对象
     * @return 比较结果（true 或 false）
     * @see Field#compare(Predicate.Op, Field)
     */
    @Override
    public boolean compare(Predicate.Op op, Field val) {
        // 强制转换为 IntField，如果不是会抛出异常
        IntField iVal = (IntField) val;

        // 根据不同的操作符执行比较
        switch (op) {
            case EQUALS:
            case LIKE: // LIKE 在整数中等同于 EQUALS
                return value == iVal.value;
            case NOT_EQUALS:
                return value != iVal.value;
            case GREATER_THAN:
                return value > iVal.value;
            case GREATER_THAN_OR_EQ:
                return value >= iVal.value;
            case LESS_THAN:
                return value < iVal.value;
            case LESS_THAN_OR_EQ:
                return value <= iVal.value;
        }

        // 默认情况不会发生，因为所有操作符都被覆盖了
        return false;
    }

    /**
     * 将该字段的值序列化到 DataOutputStream 中
     *
     * @param dos 数据输出流
     * @throws IOException 如果写入失败
     */
    @Override
    public void serialize(DataOutputStream dos) throws IOException {
        dos.writeInt(value);
    }
}
